package com.gpj.flowable.core.service.impl;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @className FlowService
 * @description
 *   TODO
 * @author GPJ
 * @date 2024/7/13 下午9:14
 * @version 1.0
 **/
@Slf4j
@Service
@FieldDefaults(level = AccessLevel.PRIVATE)
public class FlowServiceImpl implements IFlowService {
	@Autowired
	RepositoryService repositoryService;
	@Autowired
	RuntimeService runtimeService;
	@Autowired
	TaskService taskService;
	@Autowired
	HistoryService historyService;


	/**
	 * 流程部署
	 * @param name 部署名称
	 * @param resources bpmn资源文件目录集合
	 */
	@Override
	public Deployment deploy(String name, String... resources){
		DeploymentBuilder deployment = repositoryService.createDeployment();
		for (String resource : resources) {
			deployment.addClasspathResource(resource);
		}
		return deployment.name(name).deploy();
	}

	/**
	 * 根据流程部署ID获取流程定义信息
	 * @param deploymentId 流程部署ID
	 */
	@Override
	public List<ProcessDefinition> getDefinitionsByDeploymentId(String deploymentId) {
		return repositoryService.createProcessDefinitionQuery()
				.deploymentId(deploymentId)
				.active()
				.list();
	}

	/**
	 * 启动流程
	 * @param definitionId 流程定义ID
	 * @param variables 流程变量
	 */
	@Override
	public ProcessInstance run(String definitionId, Map<String, Object> variables) {
		return runtimeService.startProcessInstanceById(definitionId, variables);
	}

	/**
	 * 查询流程任务
	 * @param definitionId 流程定义
	 * @param instanceId 流程实例ID
	 * @param assignee 待审批人
	 */
	@Override
	public List<Task> getTasks(String definitionId, String instanceId, String assignee){
		return taskService.createTaskQuery()
				.processInstanceId(instanceId)
				.processDefinitionId(definitionId)
				.taskAssignee(assignee)
				.list();
	}

	/**
	 * 流程办理
	 * @param taskId 流程任务ID
	 * @param variables 流程变量
	 */
	@Override
	public void complete(String taskId, Map<String, Object> variables){
		taskService.complete(taskId, variables);
	}

	/**
	 * 流程挂起
	 * @param definitionId 流程定义ID
	 */
	@Override
	public void suspend(String definitionId){
		repositoryService.suspendProcessDefinitionById(definitionId);
	}

	/**
	 * 流程激活
	 * @param definitionId 流程定义ID
	 */
	@Override
	public void activate(String definitionId){
		repositoryService.activateProcessDefinitionById(definitionId);
	}

	/**
	 * 查询流程历史记录
	 * @param definitionId 流程定义ID
	 */
	@Override
	public List<HistoricActivityInstance> histories(String definitionId){
		return historyService.createHistoricActivityInstanceQuery()
				.processDefinitionId(definitionId)
				.finished() // 查询已完成任务
				.orderByHistoricActivityInstanceEndTime().asc() // 按照结束时间升序排列
				.list();
	}
}
